﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Xunit;
using MetaSharp.Transformation.Properties;
using System.Globalization;
using NSubstitute;
using System.Threading.Tasks;

namespace MetaSharp.Transformation.Tests.Patterns
{
	public class ObjectTests
	{
		[Fact]
		public async Task MatchesObjectSuccessfully()
		{
			var expected = new object();
            var p = Pattern.Object(typeof(object));
            var m = await Pattern.Match(p, expected);

            Assert.Same(expected, m.Value);
		}

        [Fact]
        public async Task MatchesValueTypeSuccessfully()
        {
            var p = Pattern.Object(typeof(double));
            var m = await Pattern.Match(p, 7.11);
            Assert.Equal(7.11, m.Value);
        }

        [Fact]
		public async Task MatchesWrappedTypeSuccessfully()
		{
            object expected = 7;
            var p = Pattern.Object(typeof(int));
            var m = await Pattern.Match(p, expected);
			Assert.Equal(expected, m.Value);
		}

		[Fact]
		public async Task MatchesGenericTypeSuccessfully()
		{
			var expected = new Lazy<int>();
            var p = Pattern.Object(typeof(Lazy<int>));
            var m = await Pattern.Match(p, expected);
			Assert.Equal(expected, m.Value);
		}

		[Fact]
		public async Task MatchesNullableType()
		{
			int? expected = 7;
            var p = Pattern.Object(typeof(int?));
            var m = await Pattern.Match(p, expected);
			Assert.Equal(expected, m.Value);
		}

		[Fact]
		public async Task MatchesInheritanceHierarchySuccessfully()
		{
			var expected = new ArgumentException();
            var p = Pattern.Object(typeof(Exception));
            var m = await Pattern.Match(p, expected);
			Assert.Same(expected, m.Value);
		}

		[Fact]
		public async Task MatchesInterfaceInheritanceHierarchySuccessfully()
		{
			var expected = 42;
            var p = Pattern.Object(typeof(IComparable));
            var m = await Pattern.Match(p, expected);
			Assert.Equal(expected, m.Value);
		}

		[Fact]
		public async Task ObjectPatternFailsOnEmptyStream()
		{
			var p = Pattern.Object(typeof(object));
            var m = await Pattern.Match(p, "");
			Assert.False(m.Matched);
		}

		[Fact]
		public async Task ObjectPatternFailsOnNull()
		{
            var p = Pattern.Object(typeof(object));
            var m = await Pattern.Match(p, new object[] { null });
			Assert.False(m.Matched);
		}

		[Fact]
		public async Task IncorrectTypeFailsToMatch()
		{
            var p = Pattern.Object(typeof(char));
            var m = await Pattern.Match(p, new object());
			Assert.False(m.Matched);
		}
	}
}